package cn.iocoder.mall.user.application.controller.sys;

import cn.hutool.core.util.RandomUtil;
import cn.iocoder.common.framework.constant.CommonConstant;
import cn.iocoder.common.framework.constant.ErrorCode;
import cn.iocoder.common.utils.common.api.vo.LoginInfo;
import cn.iocoder.common.utils.common.api.vo.Result;
import cn.iocoder.common.utils.common.api.vo.SMSMQDTO;
import cn.iocoder.common.utils.common.system.util.JwtUtil;
import cn.iocoder.common.utils.common.system.vo.UserInfo;
import cn.iocoder.common.utils.common.util.UUIDGenerator;
import cn.iocoder.common.utils.common.util.oConvertUtils;
import cn.iocoder.common.utils.modules.system.entity.VerificationCode;
import cn.iocoder.mall.user.application.vo.SysUser;
import cn.iocoder.mall.user.biz.dataobject.Member;
import cn.iocoder.mall.user.biz.dataobject.Seller;
import cn.iocoder.mall.user.biz.service.IMemberService;
import cn.iocoder.mall.user.biz.service.ISellerService;
import cn.iocoder.mall.user.biz.untils.RedisUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

import static cn.iocoder.common.framework.constant.CommonConstant.SMS_ROCKET_VERIFY_CODE_TOPIC;

/***
 *@author yinxucun
 *@date 2019-11-26 15:55 
 */
@RestController
@RequestMapping("/sys")
@Slf4j
public class LoginController {
    @Autowired
    RedisUtil redisUtil;

    @Autowired
    private IMemberService memberService;

    @Autowired
    private ISellerService sellerService;


    @Resource
    private RocketMQTemplate rocketMQTemplate;

    @PostMapping("/app/member/loginByMobile")
    public Result<?> memberLogin(@RequestBody LoginInfo loginInfo){
        Result result=new Result();
        result.setSuccess(false);
        if (StringUtils.isEmpty(loginInfo.getMobile())||StringUtils.isEmpty(loginInfo.getCode())){
            result.setMessage(ErrorCode.LOGIN_ERROR_INFO);
            return result;
        }

        Object o=redisUtil.getMemberCode(loginInfo.getMobile());
        if (o==null){
            result.setMessage(ErrorCode.LOGIN_CODE_TIMEOUT);
            return result;
        }
        if (! loginInfo.getCode().equals(o)){
            result.setMessage(ErrorCode.LOGIN_ERROR_PASSWOD);
            return result;
        }

        Member member=memberService.getByMobile(loginInfo.getMobile());
        if (member==null){
            member=new Member();
            member.setNickName("会员"+RandomUtil.randomString(8));
            member.setMobile(loginInfo.getMobile());
            member.setUsername(loginInfo.getMobile());
            member.setState(0);
            member.setIsDelete(0);
            member.setCreateTime(new Date());
            member.setId(UUIDGenerator.generate());
            memberService.save(member);
        }
        if (member.getState()==1){
            return Result.error("账户被冻结");
        }
        if (member.getIsDelete()==1){
            return Result.error("账户被锁定");
        }
        redisUtil.delMemberCode(loginInfo.getMobile());
        member.setPassword(loginInfo.getMobile());
        return memberInfo(member, result);

    }

    @GetMapping("/app/member/getVerificationCode")
    public Result getVerificationCodeOfMember(@RequestParam  String mobile){
        Result result=new Result();
        result.setSuccess(false);
        String code= RandomUtil.randomNumbers(4);
        redisUtil.setMemberCode(mobile,code,600);
        if (StringUtils.isEmpty(mobile)){
            result.setMessage("手机号不能为空");
            return result;
        }
        SMSMQDTO smsmqdto=new SMSMQDTO();
        smsmqdto.setMobile(mobile);
        smsmqdto.setCode(code);
        log.info("发送到mq");
        rocketMQTemplate.convertAndSend(SMS_ROCKET_VERIFY_CODE_TOPIC,smsmqdto);
        VerificationCode verificationCode=new VerificationCode();
        verificationCode.setCode(code);
        //TODO  真实发送验证码
        redisUtil.setMemberCode(mobile,code,3000);

        return Result.ok(verificationCode);
    }
    @GetMapping("/merchant/seller/getVerificationCode")
    public Result getVerificationCodeOfSeller(@RequestParam  String mobile){
        Result result=new Result();
        result.setSuccess(false);
        String code=RandomUtil.randomNumbers(4);
        VerificationCode verificationCode=new VerificationCode();
        verificationCode.setCode(code);
        redisUtil.setSellerCode(mobile,code,600);
        SMSMQDTO smsmqdto=new SMSMQDTO();
        smsmqdto.setMobile(mobile);
        smsmqdto.setCode(code);
        log.info("发送到mq");
        rocketMQTemplate.convertAndSend(SMS_ROCKET_VERIFY_CODE_TOPIC,smsmqdto);
        if (StringUtils.isEmpty(mobile)){
            result.setMessage("手机号不能为空");
            return result;
        }
        redisUtil.setSellerCode(mobile,code,3000);

        return Result.ok(verificationCode);
    }

    @PostMapping("/merchant/seller/loginByMobile")
    public Result<?> sellerLogin(@RequestBody LoginInfo loginInfo){
        Result result=new Result();
        result.setSuccess(false);
        if (StringUtils.isEmpty(loginInfo.getMobile())||StringUtils.isEmpty(loginInfo.getCode())){
            result.setMessage(ErrorCode.LOGIN_ERROR_INFO);
            result.setCode(500);
            return result;
        }

        Object o=redisUtil.getSellerCode(loginInfo.getMobile());
        if (o==null){
            result.setMessage(ErrorCode.LOGIN_CODE_TIMEOUT);
            result.setCode(500);
            return result;
        }
        if (! loginInfo.getCode().equals(o)){
            result.setMessage(ErrorCode.LOGIN_ERROR_PASSWOD);
            result.setCode(500);
            return result;
        }

        Seller seller=sellerService.getOneByMobile(loginInfo.getMobile());
        if (seller==null||seller.getState()==1||seller.getIsDelete()==1){
            return Result.error("用户不存在，请联系管理员");
        }
        redisUtil.delMemberCode(loginInfo.getMobile());
        seller.setUsername(loginInfo.getMobile());
        seller.setPassword(loginInfo.getMobile());
        return sellerInfo(seller, result);

    }

    private Result<?> sellerInfo(Seller seller, Result result) {

        UserInfo userInfo=new UserInfo();
        userInfo.setUserName(seller.getUsername());
        userInfo.setMobile(seller.getMobile());
        userInfo.setUserId(seller.getId());
        userInfo.setType(seller.getType());
        // 生成token
        String token = JwtUtil.sign(userInfo);
        redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
        // 设置超时时间
        redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME / 1000);

        // 获取用户部门信息
        JSONObject obj = new JSONObject();
        obj.put("access_token", token);
        obj.put("userInfo",seller);
        result.setResult(obj);
        result.success("登录成功");
        return result;
    }
    private Result<JSONObject> memberInfo(Member sysUser, Result<JSONObject> result) {
        // 生成token
        UserInfo userInfo=new UserInfo();
        userInfo.setUserName(sysUser.getUsername());
        userInfo.setMobile(sysUser.getMobile());
        userInfo.setUserId(sysUser.getId());
        userInfo.setType(sysUser.getType());
        String token = JwtUtil.sign(userInfo);
        redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
        // 设置超时时间
        redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME / 1000);

        // 获取用户部门信息
        JSONObject obj = new JSONObject();
        obj.put("access_token", token);
        obj.put("userInfno",sysUser);
        result.setResult(obj);
        result.success("登录成功");
        return result;
    }

    @RequestMapping(value = "/app/member/logout")
    public Result<Object> memberLogout(HttpServletRequest request, HttpServletResponse response) {
        //用户退出逻辑
        String token = request.getHeader("X-Access-Token");
        if(oConvertUtils.isEmpty(token)) {
            return Result.error("退出登录失败！");
        }
        String username = JwtUtil.getUserNameByToken();
        String userId = JwtUtil.getUserIdByToken();
        //利用用户ID和用户名唯一确定用户，防止用户名重复情况下，以下查询出错
        Member member = memberService.getOneByName(username, userId);
        if(member!=null) {
            //清空用户Token缓存
            redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token);
            //清空用户权限缓存：权限Perms和角色集合
            return Result.ok("退出登录成功！");
        }else {
            return Result.error("无效的token");
        }
    }

    @RequestMapping(value = "/merchant/seller/logout")
    public Result<Object> sellerLogout(HttpServletRequest request,HttpServletResponse response) {
        //用户退出逻辑
        String token = request.getHeader("X-Access-Token");
        if(oConvertUtils.isEmpty(token)) {
            return Result.error("退出登录失败！");
        }
        String username = JwtUtil.getUserNameByToken();
        Seller seller = sellerService.getOneByMobile(username);
        if(seller!=null) {
            //清空用户Token缓存
            redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token);
            return Result.ok("退出登录成功！");
        }else {
            return Result.error("无效的token");
        }
    }
}
